home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
ddj0897.zip
/
DYN401.ZIP
/
threads
/
pipe.d
< prev
next >
Wrap
Text File
|
1996-02-04
|
6KB
|
320 lines
/*
*
* Copyright (c) 1993-1996 Algorithms Corporation
* 3020 Liberty Hills Drive
* Franklin, TN 37067
*
* ALL RIGHTS RESERVED.
*
*
*
*/
#include <string.h>
defclass Pipe : Stream {
object iObj; /* pipe object */
char *iName;
char *iBuf;
int iBufsiz;
char *iWptr; /* write pointer (where next byte should go) */
char *iRptr; /* read pointer (where next byte will be) */
object iRblk; /* thread on read block */
object iWblk; /* thread on write block */
int iRblock;/* block reads when buffer empty */
int iWblock;/* block writes when buffer full */
struct _Pipe_iv_t *iNext;
class:
struct _Pipe_iv_t *cMpl; /* master pipe list */
};
cmeth gNewWithStrInt, <vNew> : New (object self, char *name, int bufsiz)
{
object obj = gNew(super);
ivType *iv = ivPtr(obj);
iObj = obj;
if (name) {
iName = Tnalloc(char, strlen(name)+1);
strcpy(iName, name);
}
iBuf = Tnalloc(char, bufsiz);
iBufsiz = bufsiz;
iWptr = iRptr = iBuf;
iNext = cMpl;
cMpl = iv;
return obj;
}
cmeth gNew()
{
return New(self, NULL, 128);
}
imeth int gWrite(object self, char *buf, unsigned sz)
{
int room, rroom, bytes, w=0;
if (iWblk)
return 0;
while (sz) {
/* how much room is left on the write end of the buffer? */
room = iBufsiz - (iWptr - iBuf);
/* if not enough make room from read end */
if (room < (int) sz) {
rroom = iRptr - iBuf;
if (rroom) {
bytes = iWptr - iRptr; /* bytes in buffer */
memmove(iBuf, iRptr, bytes);
iRptr = iBuf;
iWptr = iBuf + bytes;
room = iBufsiz - (iWptr - iBuf);
}
}
bytes = (int) sz > room ? room : (int) sz; /* bytes to but on buffer */
if (bytes) {
memcpy(iWptr, buf, bytes);
iWptr += bytes;
buf += bytes;
sz -= bytes;
w += bytes;
if (iRblk)
gRelease(iRblk, 0);
}
/* the following line is needed because the above release might have cause
more room - if the read thread has a higher priority */
room = iBufsiz - (iWptr - iRptr);
if (sz && !room && iWblock) { /* there is more - block */
iWblk = gFindStr(Thread, NULL);
gHold(iWblk); /* does a yield */
iWblk = NULL;
}
if (!iWblock)
break;
}
return(w);
}
imeth int gRead(object self, char *buf, unsigned sz)
{
int ba; /* bytes available */
int bg; /* bytes to get */
int tr=0; /* total bytes read */
if (iRblk)
return 0;
while (sz) {
ba = iWptr - iRptr;
bg = ba < (int) sz ? ba : (int) sz;
if (bg) {
memcpy(buf, iRptr, bg);
buf += bg;
iRptr += bg;
sz -= bg;
tr += bg;
if (iWblk)
gRelease(iWblk, 0);
}
/* the following line is needed because the above release may add bytes */
ba = iWptr - iRptr;
if (sz && !ba && iRblock) {
iRblk = gFindStr(Thread, NULL);
gHold(iRblk); /* does a yield */
iRblk = NULL;
}
if (!iRblock)
break;
}
return(tr);
}
imeth char *gGets(object self, char *buf, int sz)
{
int ba; /* bytes available */
int bg; /* bytes to get */
int tr=0; /* total bytes read */
if (!(iWptr - iRptr) && !iRblock || iRblk || sz <= 0)
return NULL;
if (sz-- == 1) {
*buf = '\0';
return buf;
}
while (sz) {
ba = iWptr - iRptr;
for (bg=0 ; bg < ba && bg < sz && iRptr[bg++] != '\n' ; );
if (iRptr[bg-1] == '\n')
sz = bg;
if (bg) {
memcpy(buf, iRptr, bg);
buf += bg;
iRptr += bg;
sz -= bg;
tr += bg;
if (iWblk)
gRelease(iWblk, 0);
}
/* the following line is needed because the above release may add bytes */
ba = iWptr - iRptr;
if (sz && !ba && iRblock) {
iRblk = gFindStr(Thread, NULL);
gHold(iRblk); /* does a yield */
iRblk = NULL;
}
if (!iRblock)
break;
}
buf[tr] = '\0';
return buf;
}
imeth object gDispose, gGCDispose, gDeepDispose (object self)
{
ivType *t, *pt;
if (iRblk || iWblk)
return NULL;
for (t=cMpl, pt=NULL ; t ; pt=t, t=t->iNext)
if (t == iv) {
if (pt)
pt->iNext = t->iNext;
else
cMpl = t->iNext;
break;
}
if (iName) {
free(iName);
iName = NULL;
}
if (iBuf) {
free(iBuf);
iBuf = NULL;
}
return gDispose(super);
}
cmeth object gFindStr, <vFind> (object self, char *name)
{
ivType *p;
USE(self);
if (!name)
return NULL;
for (p=cMpl ; p ; p=p->iNext)
if (p->iName && !strcmp(p->iName, name))
return p->iObj;
return NULL;
}
imeth long gLength(object self)
{
#if 0
if (iRblock && !(iWptr - iRptr)) {
iRblk = gFindStr(Thread, NULL);
gHold(iRblk); /* does a yield */
iRblk = NULL;
}
#endif
return iWptr - iRptr;
}
imeth int gRoom(object self)
{
#if 0
if (iWblock && !(iBufsiz - (iWptr - iRptr))) {
iWblk = gFindStr(Thread, NULL);
gHold(iWblk); /* does a yield */
iWblk = NULL;
}
#endif
return iBufsiz - (iWptr - iRptr);
}
imeth int gSize(object self)
{
return iBufsiz;
}
imeth char *gName(object self)
{
return iName;
}
imeth gMode(object self, int rblock, int wblock)
{
iRblock = rblock;
iWblock = wblock;
return self;
}
imeth long gAdvance(object self, long sz)
{
int ba; /* bytes available */
int bg; /* bytes to get */
long tr=0; /* total bytes read */
if (iRblk)
return 0;
while (sz) {
ba = iWptr - iRptr;
bg = (long) ba < sz ? ba : (int) sz;
if (bg) {
iRptr += bg;
sz -= bg;
tr += bg;
if (iWblk)
gRelease(iWblk, 0);
}
/* the following line is needed because the above release may add bytes */
ba = iWptr - iRptr;
if (sz && !ba && iRblock) {
iRblk = gFindStr(Thread, NULL);
gHold(iRblk); /* does a yield */
iRblk = NULL;
}
if (!iRblock)
break;
}
return(tr);
}
imeth long gPosition(object self)
{
USE(self);
return 0L;
}
imeth int gEndOfStream(object self)
{
return !(iWptr - iRptr);
}
/*
*
* Copyright (c) 1993-1996 Algorithms Corporation
* 3020 Liberty Hills Drive
* Franklin, TN 37067
*
* ALL RIGHTS RESERVED.
*
*
*
*/